package io.mft.dev.base.config;

import java.io.File;
import java.io.FileOutputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.yaml.snakeyaml.DumperOptions.FlowStyle;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.nodes.Tag;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.json.JSONUtil;
import io.mft.api.domain.ApiFunctionType;
import io.mft.commons.config.ConfigProvider;
import io.mft.commons.exception.MFTException;
import io.mft.dev.base.config.builder.CatalogApiBuilder;
import io.mft.dev.base.config.builder.CatalogApiBuilder.CatalogApi;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class ApiCatalogYamlEditor {
	Map<String, Object> map = new LinkedHashMap<String, Object>();
	List<List<Map<String, Object>>> apiLists=new ArrayList<>();
	Map<String, CatalogApi> temp=new HashMap<String, CatalogApiBuilder.CatalogApi>();
	public void addCatalogApi(CatalogApi catalogApi) {
		if (temp.containsKey(catalogApi.getKey())) {
			log.warn("存在相同的API定义,忽略当前API,详情:"+JSONUtil.toJsonStr(catalogApi));
			return;
		}
		Map<String, Object> sysMap = ConfigProvider.getMapValue(map, catalogApi.getSystemKey());
		if (sysMap == null) {
			sysMap = new LinkedHashMap<>();
			map.put(catalogApi.getSystemKey(), sysMap);
		}
		Map<String, Object> moduleMap = ConfigProvider.getMapValue(sysMap, catalogApi.getModuleKey());
		if (moduleMap == null) {
			moduleMap = new LinkedHashMap<>();
			sysMap.put(catalogApi.getModuleKey(), moduleMap);
		}
		Map<String, Object> apisMap = ConfigProvider.getMapValue(moduleMap, "apis");
		if (apisMap == null) {
			apisMap = new LinkedHashMap<>();
			moduleMap.put("apis", apisMap);
		}
		List<Map<String, Object>> apiList = ConfigProvider.getMapValue(apisMap, catalogApi.getApiFunctionType().name());
		if (apiList == null) {
			apiList = new ArrayList<>();
			apiLists.add(apiList);
			apisMap.put(catalogApi.getApiFunctionType().name(), apiList);
		}
		Map<String, Object> api = BeanUtil.beanToMap(catalogApi);
		api.remove("systemKey");
		api.remove("moduleKey");
		api.remove("apiFunctionType");
		if (catalogApi.getMaxPoolSize() == 0) {
			api.remove("maxPoolSize");
		}
		if (catalogApi.getWorkQueueCapacity() == 0) {
			api.remove("workQueueCapacity");
		}
		apiList.add(api);
		temp.put(catalogApi.getKey(), catalogApi);
	}

	public void addApiThreadExecutor(String systemKey,String moduleKey,int maxPoolSize,int workQueueCapacity) {
		Map<String, Object> sysMap = ConfigProvider.getMapValue(map, systemKey);
		if (sysMap == null) {
			sysMap = new LinkedHashMap<>();
			map.put(systemKey, sysMap);
		}
		Map<String, Object> moduleMap = ConfigProvider.getMapValue(sysMap, moduleKey);
		if (moduleMap == null) {
			moduleMap = new LinkedHashMap<>();
			sysMap.put(moduleKey, moduleMap);
		}
		Map<String, Object> config=new LinkedHashMap<>();
		config.put("maxPoolSize", maxPoolSize);
		config.put("workQueueCapacity", workQueueCapacity);
		moduleMap.put("apiThreadExecutor", config);
	}
	public String toYamlString(String dir) {
		try {
			apiLists.forEach(list->{
				list.sort(new Comparator<Map<String, Object>>() {

					@Override
					public int compare(Map<String, Object> o1, Map<String, Object> o2) {
						String id1=String.valueOf(o1.get("key"));
						String id2=String.valueOf(o2.get("key"));
						return id1.compareToIgnoreCase(id2);
					}
				});
			});
			Yaml yaml = new Yaml();
			String text= yaml.dumpAs(map, Tag.MAP, FlowStyle.AUTO);
					//yaml.dumpAsMap(map);
			File dirFile=new File(dir);
			if (!dirFile.exists()) {
				dirFile.mkdirs();
			}
			String path=dir+File.separator+"apiCatalog.yml";
			File file=new File(path);
			if (file.exists()) {
				file.delete();
			}
			file.createNewFile();
			FileOutputStream out=new FileOutputStream(file);
			IoUtil.writeUtf8(out, true, text);
			//log.info("接口目录配置文件查看路径:"+path);
			return text;
		} catch (Exception e) {
			throw new MFTException(e);
		}

	}
	public String toYamlString(boolean devMode) {
		try {
			URL url=this.getClass().getClassLoader().getResource(".");
			File dir=new File(url.getPath());
			if (devMode) {
				dir=dir.getParentFile().getParentFile();
			}
			return toYamlString(dir.getPath());
		} catch (Exception e) {
			throw new MFTException(e);
		}

	}
	
	
	
	public static void main(String[] args) {
		ApiCatalogYamlEditor apiCatalogYamlEditor=new ApiCatalogYamlEditor();
		
		apiCatalogYamlEditor.addApiThreadExecutor("selfstock", "stockManager", 2, 1024);
		
		
		String[] combinationApikeys=new String[] {"3001506","3001507","3001525"};
		for (String key : combinationApikeys) {
			CatalogApi api=new CatalogApi();
			api.setApiFunctionType(ApiFunctionType.combination);
			api.setKey(key);
			api.setMaxPoolSize(1);
			api.setWorkQueueCapacity(6000);
			api.setSystemKey("selfstock");
			api.setModuleKey("stockManager");
			apiCatalogYamlEditor.addCatalogApi(api);
		}
		String[] processExecutorApikeys=new String[] {"2051001","2051002","2051003","2051006","2051007"};
		for (String key : processExecutorApikeys) {
			CatalogApi api=new CatalogApi();
			api.setApiFunctionType(ApiFunctionType.processExecutor);
			api.setKey(key);
			api.setSystemKey("selfstock");
			api.setModuleKey("stockManager");
			apiCatalogYamlEditor.addCatalogApi(api);
		}
		
		String stringYaml=apiCatalogYamlEditor.toYamlString(true);
		System.err.println(stringYaml);
	}
}
